package edu.zcmu.seckill.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import edu.zcmu.seckill.entity.Product;
import edu.zcmu.seckill.entity.SeckillProduct;
import edu.zcmu.seckill.entity.SeckillProductPolicy;
import edu.zcmu.seckill.enumeration.GlobalEnum;
import edu.zcmu.seckill.exception.MyException;
import edu.zcmu.seckill.mapper.SeckillProductMapper;
import edu.zcmu.seckill.response.ResultCode;
import edu.zcmu.seckill.service.SeckillProductPolicyService;
import edu.zcmu.seckill.service.SeckillProductService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import edu.zcmu.seckill.vo.SeckillProductVo;
import net.bytebuddy.implementation.bytecode.Throw;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 唐诗
 * @since 2022-02-22
 */
@Service
public class SeckillProductServiceImpl extends ServiceImpl<SeckillProductMapper, SeckillProduct> implements SeckillProductService {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    SeckillProductPolicyService seckillProductPolicyService;

    @Value("${product.default.img}")
    String defaultImg;
    /**
     * @Author tang
     * @Date 2022/1/22
     * @Description: 上架秒杀产品
     */
    @Override
    public void uploadSeckillProductCache() {
        ValueOperations valueOperations = redisTemplate.opsForValue();
        List<SeckillProduct> seckillProducts = this.baseMapper.selectList(null);
        if (seckillProducts!=null && seckillProducts.size()>0){
            seckillProducts.forEach(item->{
                if (StringUtils.isEmpty(item.getImg())){
                    item.setImg(defaultImg);
                }
                SeckillProductPolicy  policy= seckillProductPolicyService.getSeckillProductPolicyById(item.getId());
                String productPolicy = encapsulationSecKillProductPolicy(policy);
                valueOperations.set(GlobalEnum.GET_SECKILL_PRODUCT_REDIS.getCode()+item.getId(),JSON.toJSONString(item));
                if(item.getSale()==null){
                    item.setSale(0);
                }
                Integer c = item.getCount()-item.getSale();
                valueOperations.set(GlobalEnum.GET_SECKILL_PRODUCT_COUNT_REDIS.getCode() + item.getId(),c.toString());
                valueOperations.set(GlobalEnum.GET_SECKILL_PRODUCT_POLICY_REDIS.getCode()+ item.getId(),productPolicy);

            });
            valueOperations.set(GlobalEnum.GET_ALL_SECKILL_PRODUCT_REDIS.getCode(), JSON.toJSONString(seckillProducts));
        }

    }


    /**
     * 封装秒杀产品的购买条件
     * @param policy
     * @return
     */
    public String encapsulationSecKillProductPolicy(SeckillProductPolicy policy){
        String policyCondition="";
        if (policy==null){
            return "111_18";
        }
        if (policy.getOverdue()==null||policy.getOverdue()==1){
            policyCondition=policyCondition+"1";
        }else{
            policyCondition=policyCondition+"0";
        }

        if (policy.getJob()==null||policy.getJob()==1){
            policyCondition=policyCondition+"1";
        }else{
            policyCondition=policyCondition+"0";
        }

        if (policy.getDishonesty()==null||policy.getDishonesty()==1){
            policyCondition=policyCondition+"1";
        }else{
            policyCondition=policyCondition+"0";
        }

        if (policy.getAgeSize()==null){
            policyCondition=policyCondition+"_18";
        }else {
            policyCondition=policyCondition+"_"+policy.getAgeSize().toString();
        }
        return policyCondition;
    }


    /**
     * 获取当前正在秒杀的产品
     * @param pageNum
     * @return
     */
    @Override
    public HashMap<String,Object> getNow(Integer pageNum) {

        ValueOperations valueOperations = redisTemplate.opsForValue();
        HashMap<String, Object> map = new HashMap<>(2);
        String seckillProduct = (String) valueOperations.get(GlobalEnum.GET_ALL_SECKILL_PRODUCT_REDIS.getCode());
        if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isBlank(seckillProduct)){
            map.put("total",0);
            map.put("data",null);
            return map;
        }
        List<SeckillProduct> products = JSON.parseArray(seckillProduct,SeckillProduct.class);


        LinkedList<SeckillProduct> seckillProducts = new LinkedList<>();

        Date nowDate = new Date(System.currentTimeMillis());

        for (SeckillProduct product : products) {
            if(!nowDate.before(product.getStartTime())&&!nowDate.after(product.getEndTime())){
                String o = (String) valueOperations.get(GlobalEnum.GET_SECKILL_PRODUCT_COUNT_REDIS.getCode() + product.getId());
                product.setSale(product.getCount()-Integer.valueOf(o));
                seckillProducts.add(product);
            }
        }

        map.put("total",seckillProducts.size());
        map.put("data",this.getEightInfo(seckillProducts,pageNum));
        return map;
    }

    /**
     * 获取预热中的产品
     * @param pageNum
     * @return
     */
    @Override
    public HashMap<String, Object> getBefore(Integer pageNum) {
        ValueOperations valueOperations = redisTemplate.opsForValue();
        HashMap<String, Object> map = new HashMap<>(2);
        String seckillProduct = (String) valueOperations.get(GlobalEnum.GET_ALL_SECKILL_PRODUCT_REDIS.getCode());
        if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isBlank(seckillProduct)){
            map.put("total",0);
            map.put("data",null);
            return map;
        }
        List<SeckillProduct> products = JSON.parseArray(seckillProduct,SeckillProduct.class);

        LinkedList<SeckillProduct> seckillProducts = new LinkedList<>();

        Date nowDate = new Date(System.currentTimeMillis());
        for (SeckillProduct product : products) {
            if(nowDate.before(product.getStartTime())){
                seckillProducts.add(product);
            }
        }

        map.put("total",seckillProducts.size());
        map.put("data",this.getEightInfo(seckillProducts,pageNum));
        return map;
    }

    /**
     * 获取过期的产品
     * @param pageNum
     * @return
     */
    @Override
    public HashMap<String, Object> getAfter(Integer pageNum) {
        ValueOperations valueOperations = redisTemplate.opsForValue();
        HashMap<String, Object> map = new HashMap<>(2);
        String seckillProduct = (String) valueOperations.get(GlobalEnum.GET_ALL_SECKILL_PRODUCT_REDIS.getCode());
        if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isBlank(seckillProduct)){
            map.put("total",0);
            map.put("data",null);
            return map;
        }
        List<SeckillProduct> products = JSON.parseArray(seckillProduct,SeckillProduct.class);

        LinkedList<SeckillProduct> seckillProducts = new LinkedList<>();

        Date nowDate = new Date(System.currentTimeMillis());
        for (SeckillProduct product : products) {
            if(nowDate.after(product.getEndTime())){
                seckillProducts.add(product);
            }
        }

        map.put("total",seckillProducts.size());
        map.put("data",this.getEightInfo(seckillProducts,pageNum));
        return map;
    }

    /**
     * 根据id获取秒杀产品信息
     * @param id
     * @return
     */
    @Override
    public HashMap<String,Object> getSeckillProductById(Integer id) {
        String product = (String) redisTemplate.opsForValue().get(GlobalEnum.GET_SECKILL_PRODUCT_REDIS.getCode() + id);
        if (StringUtils.isEmpty(product)){
            throw new MyException(ResultCode.ERROR,"该商品不存在");
        }
        String o = (String) redisTemplate.opsForValue().get(GlobalEnum.GET_SECKILL_PRODUCT_POLICY_REDIS.getCode() + id);

        SeckillProduct parse = JSON.parseObject(product,SeckillProduct.class);

        SeckillProductVo productVo = new SeckillProductVo();
        BeanUtils.copyProperties(parse,productVo);
        Date nowDate = new Date(System.currentTimeMillis());//当前时间
        if(!nowDate.before(productVo.getStartTime())&&!nowDate.after(productVo.getEndTime())){
            String sale = (String) redisTemplate.opsForValue().get(GlobalEnum.GET_SECKILL_PRODUCT_COUNT_REDIS.getCode() + parse.getId());
            productVo.setSale(parse.getCount()-Integer.valueOf(sale));
            //秒杀中
            productVo.setState("秒杀中");
        }else if (nowDate.before(productVo.getStartTime())){
            //产品秒杀时间未到
            productVo.setState("未开始");
        }else{
            productVo.setState("已结束");
        }
        HashMap<String, Object> map = new HashMap<>(2);
        map.put("policy",o);
        map.put("data",productVo);
        return map;
    }

    /**
     * 更新秒杀产品销售量
     * @param id
     * @param i
     */
    @Override
    public void updateProductBySale(String id, int i) {
        SeckillProduct product = new SeckillProduct();
        product.setId(Integer.valueOf(id));
        product.setSale(product.getSale()+i);
        baseMapper.updateById(product);
    }

    //根据页码获取八条数据
    public List getEightInfo(List list, Integer page) {
        if (list == null || list.size() <= 0) {
            return null;
        }
        ArrayList<Object> objects = new ArrayList(8);
        int index = (page - 1) * 8;
        int length = list.size();
        for (int i = 0; i < 8; i++) {
            if (index < length) {
                objects.add(list.get(index++));
            } else {
                break;
            }
        }
        return objects;
    }


}
